package primitive3D;

import java.util.ArrayList;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import rayTracer.AABB;
import rayTracer.Ray;
import rayTracer.Shader;
import rayTracer.Transformation;

public abstract class Primitive3D implements Cloneable{
	public ArrayList<Primitive3D> components;
	public String name;
	public Shader shader;
	protected Point3d position;	
	public AABB bb = null;
	public boolean marked = false;
	
	public void setName( String name ){
		this.name = new String(name);		
	}
	
	public String getName(){
		return new String(name);
	}
	
	public Point3d getPosition(){
		return new Point3d(position);
	}
		
	public Object clone() throws CloneNotSupportedException{		
        Primitive3D obj=null;
        try{
            obj=(Primitive3D)super.clone();
        }catch(CloneNotSupportedException ex){
        	//ex.printStackTrace();
        	System.out.println(ex.getMessage());
        }        
        obj.name = new String( name );
        obj.position = (Point3d)position.clone();
        
        return obj;    
	}
	
	public ArrayList<Primitive3D> getPrimitives(){
		if( components == null )
			return null;
		
		ArrayList<Primitive3D> ans = new ArrayList<Primitive3D>();
		for( int i=0 ; i < components.size() ; i++ ){
			ans.add(components.get(i));		
		}
		return ans;
	}
	
	public abstract void scaleFromReferencePosition(Point3d referencePosition, double scaleFactor);	
	public abstract void setPosition( Point3d otherPosition );
	public abstract String toString();
	public abstract double intersects(Ray ray);
	public abstract int transform(Transformation trans);
	
	
	protected void scalePointfromReferencePosition(Point3d point, Point3d refencePosition, double scaleFactor){
		Vector3d vector = new Vector3d();
		vector.sub(point, refencePosition);
		vector.scale(scaleFactor);
		point.add(refencePosition, vector);		
	}
	
	// Devuelve un vector normal a la superficie de la primitiva que pasa por p
	// p debe ser un punto de la superficie de la primitiva
	public abstract Vector3d getNormal(Point3d p);
	
}
